---
title: ルーティング
description: Astroのルーティングの紹介
i18nReady: true
---
import { FileTree } from '@astrojs/starlight/components';
import RecipeLinks from "~/components/RecipeLinks.astro"
import Since from '~/components/Since.astro'
import ReadMore from '~/components/ReadMore.astro'

Astroは**ファイルベースルーティング**を使用して、プロジェクトの`src/pages/`ディレクトリのファイルレイアウトを元にビルドURLを生成します。

## ページ間の移動

Astroでは、ルート間の移動に標準的なHTMLの[`<a>`要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/a)を使用します。フレームワーク固有の`<Link>`コンポーネントは提供されていません。

```astro title="src/pages/index.astro"
<p>Astroの<a href="/about/">概要</a>についてもっと読む！</p>
```

## 静的ルーティング

`src/pages/`ディレクトリにある`.astro`[ページコンポーネント](/ja/basics/astro-pages/)、MarkdownとMDXファイル（`.md`、`.mdx`）は、**自動的にウェブサイトのページとなります**。各ページのルートは、`src/pages/`ディレクトリ内における自身のパスとファイル名に対応します。

```diff
# 静的ルーティングの例
src/pages/index.astro        -> mysite.com/
src/pages/about.astro        -> mysite.com/about
src/pages/about/index.astro  -> mysite.com/about
src/pages/about/me.astro     -> mysite.com/about/me
src/pages/posts/1.md         -> mysite.com/posts/1
```

:::tip
Astroのプロジェクトでは、別途「ルーティング設定」を管理する必要はありません。`src/pages/`ディレクトリにファイルを配置すると、新しいルートが自動的に作成されます。静的ビルドでは、[`build.format`](/ja/reference/configuration-reference/#buildformat)設定オプションを使用してファイルの出力形式をカスタマイズできます。
:::


## 動的ルーティング

Astroページファイルのファイル名に動的ルートパラメータを指定すると、ファイルにマッチするページを複数生成できます。たとえば`src/pages/authors/[author].astro`は、ブログの各著者に対してプロフィールページを生成します。`author`は、ページ内からアクセス可能な*パラメーター*となります。

Astroのデフォルトの静的出力モードでは、これらのページはビルド時に生成されるため、`author`と対応するファイルを取得する場合、それらのリストを事前に決めておく必要があります。SSRモードでは、ルートにマッチしたリクエストに応じてページが生成されます。

### 静的（SSG）モード

すべてのルートをビルド時に決める必要があるため、動的ルートは`getStaticPaths()`をエクスポートし、そこで`params`プロパティをもつオブジェクトの配列を返す必要があります。各オブジェクトは対応するルートを生成します。

`[dog].astro`はファイル名に動的な`dog`パラメーターが定義されているため、`getStaticPaths()`から返されるオブジェクトの`params`には`dog`を含める必要があります。`Astro.params`を使用してページからこのパラメーターにアクセスできます。

```astro title="src/pages/dogs/[dog].astro"
---
export function getStaticPaths() {
  return [
    {params: {dog: 'clifford'}},
    {params: {dog: 'rover'}},
    {params: {dog: 'spot'}},
  ];
}

const { dog } = Astro.params;
---
<div>いい子だ、{dog}！</div>
```

上のコードにより、`/dogs/clifford`、`/dogs/rover`、`/dogs/spot`という3つのページが生成され、各ページでは対応する犬の名前が表示されます。

ファイル名には複数のパラメーターを含められますが、これらをすべて`getStaticPaths()`の`params`オブジェクトに含める必要があります。

```astro title="src/pages/[lang]-[version]/info.astro"
---
export function getStaticPaths () {
 return [
    {params: {lang: 'en', version: 'v1'}},
    {params: {lang: 'fr', version: 'v2'}},
  ];
}

const { lang, version } = Astro.params;
---
...
```

上のコードは`/en-v1/info`と`/fr-v2/info`を生成します。

パラメーターはパス内の異なる部分に設定できます。たとえば、上と同じ`getStaticPaths()`をもつ`src/pages/[lang]/[version]/info.astro`ファイルは、`/en/v1/info`と`/fr/v2/info`のルートを生成します。

<ReadMore>[`getStaticPaths()`](/ja/reference/api-reference/#getstaticpaths)についてもっと学ぶ。</ReadMore>

<RecipeLinks slugs={["ja/recipes/i18n"]} />

#### レストパラメーター

より柔軟なURLルーティングが必要な場合は、`.astro`ファイル名に[レストパラメーター](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters)（`[...path]`）を使用することで、任意の深さのファイルパスにマッチさせられます。

```astro title="src/pages/sequences/[...path].astro"
---
export function getStaticPaths() {
  return [
    {params: {path: 'one/two/three'}},
    {params: {path: 'four'}},
    {params: {path: undefined }}
  ]
}

const { path } = Astro.params;
---
...
```

上のコードは`/sequences/one/two/three`、`/sequences/four`、`/sequences`を生成します。（レストパラメーターを`undefined`に設定することで、トップレベルのページにマッチさせられます。）

レストパラメーターは**他の名前付きパラメーター**と組み合わせて使用できます。たとえば、GitHubのファイルビューアは以下の動的ルートで表現できます。

```
/[org]/[repo]/tree/[branch]/[...file]
```

この例では、`/withastro/astro/tree/main/docs/public/favicon.svg`へのリクエストは、以下の名前付きパラメーターへと分割されます。

```js
{
	org: 'withastro',
	repo: 'astro',
	branch: 'main',
	file: 'docs/public/favicon.svg'
}
```

#### 複数レベルの動的ページの例

以下の例は、レストパラメーター（`[...slug]`）と`getStaticPaths()`の[`props`](/ja/reference/api-reference/#data-passing-with-props)機能を使用して、異なる深さのスラグに対してページを生成します。

```astro title="src/pages/[...slug].astro"
---
export async function getStaticPaths() {
  const pages = [
    {
      slug: undefined,
      title: "Astroストア",
      text: "Astroにようこそ！",
    },
    {
      slug: "products",
      title: "Astroグッズ",
      text: "たくさんの商品があります",
    },
    {
      slug: "products/astro-handbook",
      title: "究極のAstroハンドブック",
      text: "Astroについて学びたければ、この本を読む必要があります",
    },
  ];
  return pages.map(({ slug, title, text }) => {
    return {
      params: { slug },
      props: { title, text },
    };
  });
}

const { title, text } = Astro.props;
---
<html>
  <head>
    <title>{title}</title>
  </head>
  <body>
    <h1>{title}</h1>
    <p>{text}</p>
  </body>
</html>
```

### サーバー（SSR）モード

[SSR](/ja/guides/server-side-rendering/)モードでも、動的ルートは同じように定義されます。つまり、任意の文字列やパスにマッチさせるために、ファイル名に`[param]`や`[...path]`などのブラケットを含められます。しかし、各ルートは事前にビルドされないため、マッチしたすべてのルートに対してページが提供されます。これらは「静的」ルートではないため、`getStaticPaths`は使用できません。

```astro title="src/pages/resources/[resource]/[id].astro"
---
const { resource, id } = Astro.params;
---
<h1>{resource}: {id}</h1>
```

このページは、`resources/users/1`や`resources/colors/blue`など、任意の`resource`と`id`に対して提供されます。

#### `[...slug]`の例をSSR用に変更する

SSRページでは`getStaticPaths()`を使用できないため、propsを受け取れません。しかし、オブジェクト内の`slug`パラメーターの値を参照することで、[前の例](#複数レベルの動的ページの例)をSSRモードにも対応させられます。"/"に対応するルートの場合、スラグパラメーターは`undefined`になります。値がオブジェクトに存在しない場合は、404ページにリダイレクトします。

```astro title="src/pages/[...slug].astro"
---
const pages = [
  {
    slug: undefined,
    title: "Astroストア",
    text: "Astroにようこそ！",
  },
  {
    slug: "products",
    title: "Astroグッズ",
    text: "たくさんの商品があります",
  },
  {
    slug: "products/astro-handbook",
    title: "究極のAstroハンドブック",
    text: "Astroについて学びたければ、この本を読む必要があります",
  },
];

const { slug } = Astro.params;
const page = pages.find((page) => page.slug === slug);
if (!page) return Astro.redirect("/404");
const { title, text } = page;
---
<html>
<head>
  <title>{title}</title>
</head>
<body>
  <h1>{title}</h1>
  <p>{text}</p>
</body>
</html>
```

## リダイレクト

読者を新しいページにリダイレクトしなければならない場合があります。サイトの構造が変更されたために永久的にリダイレクトする必要がある場合や、認証されたルートにログインするといったアクションに応じておこなう場合などです。

Astroの設定で、[永久的に移動したページにユーザーをリダイレクト](#リダイレクトの設定)するルールを定義できます。また、ユーザーがサイトを利用した際に[動的にリダイレクト](#動的リダイレクト)することもできます。

### リダイレクトの設定

<p><Since v="2.9.0" /></p>

`redirects`値を使用して、Astroの設定から永久的なリダイレクトのマッピングを指定できます。ほとんどのリダイレクトでは、これは古いルートから新しいルートへのマッピングとなります。

```js title="astro.config.mjs" {4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
  redirects: {
    '/old-page': '/new-page'
  }
});
```

このリダイレクトは、ファイルベースルーティングと同じルールに従います。たとえば、新しいルートと古いルートの両方に同じパラメーターが含まれていれば、動的ルートも可能です。

```js
{
  "/blog/[...slug]": "/articles/[...slug]"
}
```

SSRまたは静的アダプターを使用するとオブジェクトを値として設定でき、そこで`status`コードや新しい`destination`を指定できます。

```js title="astro.config.mjs" {5-8}
import { defineConfig } from 'astro/config';

export default defineConfig({
  redirects: {
    '/old-page': {
      status: 302,
      destination: '/new-page'
    }
  }
});
```

`astro build`の実行時に、Astroはデフォルトで[meta refresh](https://developer.mozilla.org/ja/docs/Web/HTML/Element/meta#examples)タグを含むHTMLファイルを出力します。サポートされているアダプターの場合は、代わりにホストの設定ファイルにリダイレクトを含めて出力します。

ステータスコードはデフォルトで`301`です。HTMLファイルをビルドする場合、ステータスコードはサーバーによって使用されません。

### 動的リダイレクト

`Astro`グローバルの`Astro.redirect`メソッドを使用すると、別のページに動的にリダイレクトできます。たとえばクッキーからセッションを取得してユーザーのログイン状態を確認した後などにこれをおこないます。

```astro title="src/pages/account.astro" {8}
---
import { isLoggedIn } from '../utils';

const cookie = Astro.request.headers.get('cookie');

// ユーザーがログインしていない場合は、ログインページにリダイレクトします
if (!isLoggedIn(cookie)) {
  return Astro.redirect('/login');
}
---
<html>
  <!-- ページの内容... -->
</html>
```

## ルーティングの優先順位

複数のルートが同じURLパスをビルドする可能性があります。たとえば、これらのルートはすべて`/posts/create`をビルドできます。

<FileTree>
- src/pages/
  - [...slug].astro
  - posts/
    - create.astro
    - [page].astro
    - [pid].ts
    - [...slug].astro
</FileTree>

Astroは、ページをビルドするためにどのルートを使用すべきかを知る必要があります。そのために、以下のルールを順に適用してルートの順番を決定します。

- より多くのパスセグメントを持つルートが、詳細度が低いルートよりも優先される。上の例では、`/posts/`配下のすべてのルートが、`/[...slug].astro`よりも優先される。
- パスパラメーターを持たない静的ルートは、動的ルートより優先される。例えば、`/posts/create.astro`は、他のすべてのルートよりも優先される。
- 名前付きパラメーターを使用する動的ルーティングは、レストパラメーターよりも優先される。例えば、`/posts/[page].astro`は`/posts/[...slug].astro`よりも優先される。
- 事前レンダリングされた動的ルートは、サーバーの動的ルートよりも優先される。
- エンドポイントはページよりも優先される。
- ルートを上記のルールで解決できない場合、Nodeのデフォルトロケールに基づいてアルファベット順に解決される。

上記のようにファイルが配置されている場合に、リクエストされたURLと、HTMLをビルドするために使用されるルートがどのようにマッチングされるかの例をいくつか見てみましょう。

- `pages/posts/create.Astro` - `/posts/create`だけをビルドします
- `pages/posts/[pid].ts` - `/posts/abc`、`/posts/xyz`などをビルドします。しかし、`/posts/create`はビルドしません
- `pages/posts/[page].astro` - `/posts/1`、`/posts/2`などをビルドします。しかし、`/posts/create`、`/posts/abc`、`/posts/xyz`はビルドしません
- `pages/posts/[...slug].astro` - `/posts/1/2`、`/posts/a/b/c`などをビルドします。しかし、`/posts/create`、`/posts/1`、`/posts/abc`などはビルドしません
- `pages/[...slug].astro` - `/abc`、`/xyz`、`/abc/xyz`などをビルドします。しかし、`/posts/create`、`/posts/1`、`/posts/abc`などはビルドしません

## ページネーション

Astroは、複数のページに分割する必要がある大規模なデータコレクションのために、ページネーションを組み込みでサポートしています。Astroは、前ページと次ページのURL、総ページ数など、一般的なページネーションプロパティを生成します。

ページネーションされるルート名には、標準的な動的ルートと同じ`[ブラケット]`構文を使用する必要があります。たとえば、ファイル名 `/astronauts/[page].astro` は `/astronauts/1`, `/astronauts/2` などのルートを生成し、`[page]`は生成されるページ番号となります。

`paginate()`関数を使用すると、次のように値の配列に対してこれらのページを生成できます。

```astro /{ (paginate) }/ /paginate\\(.*\\)/ /(?<=const.*)(page)/ /page\\.[a-zA-Z]+/
---
// src/pages/astronauts/[page].astro
export async function getStaticPaths({ paginate }) {
  const astronautPages = [{
    astronaut: 'ニール・アームストロング',
  }, {
    astronaut: 'バズ・オルドリン',
  }, {
    astronaut: 'サリー・ライド',
  }, {
    astronaut: 'ジョン・グレン',
  }];
  // 宇宙飛行士の配列から、1ページに2人づつ入るようにページを生成します
  return paginate(astronautPages, { pageSize: 2 });
}
// ページネーションされたデータは、すべて"page"プロパティとして渡されます
const { page } = Astro.props;
---

<!--現在のページ番号を表示します。Astro.params.pageも使用可能です！-->
<h1>{page.currentPage}ページ</h1>
<ul>
  <!--宇宙飛行士情報の配列を列挙します-->
  {page.data.map(({ astronaut }) => <li>{astronaut}</li>)}
</ul>
```

これで、1ページに2つのアイテムが配置された、以下のページが生成されます。
- `/astronauts/1` - 1ページ目には「ニール・アームストロング」と「バズ・オルドリン」を表示します
- `/astronauts/2` - 2ページ目には「サリー・ライド」と「ジョン・グレン」を表示します


### `page` プロパティ

`paginate()`関数を使用すると、各ページのデータは`page`プロパティで渡されます。`page`プロパティは多くの便利なプロパティを持っていますが、ここではそのうち重要なものを紹介します。
- **page.data** - `paginate()`関数に渡された、ページのスライスデータを含む配列です
- **page.url.next** - セット内の次のページへのリンクです
- **page.url.prev** - セット内の前のページへのリンクです

```astro /(?<=const.*)(page)/ /page\\.[a-zA-Z]+(?:\\.(?:prev|next))?/
---
// src/pages/astronauts/[page].astro
// 前の例と同じように、{ astronaut } オブジェクトのリストをページネーションします
export async function getStaticPaths({ paginate }) { /* ... */ }
const { page } = Astro.props;
---
<h1>{page.currentPage}ページ</h1>
<ul>
  {page.data.map(({ astronaut }) => <li>{astronaut}</li>)}
</ul>
{page.url.prev ? <a href={page.url.prev}>Previous</a> : null}
{page.url.next ? <a href={page.url.next}>Next</a> : null}
```


#### 完全なAPIリファレンス

```ts
interface Page<T = any> {
	/** 結果 */
	data: T[];
	/** メタデータ */
	/** 0から始まる、ページ上の最初のアイテムのインデックス */
	start: number;
	/** 0から始まる、ページ上の最後のアイテムのインデックス */
	end: number;
	/** 結果の総数 */
	total: number;
	/** 1から始まる、現在のページ番号 */
	currentPage: number;
	/** 1ページあたりのアイテム数（デフォルトは25） */
	size: number;
	/** 最終ページ番号 */
	lastPage: number;
	url: {
		/** 現在のページのURL */
		current: string;
		/** 前のページのURL（もしあれば） */
		prev: string | undefined;
		/** 次のページのURL（もしあれば） */
		next: string | undefined;
	};
}
```

### ネストされたページネーション

ページネーションのより高度なユースケースは**ネストされたページネーション**です。これは、ページネーションを他の動的ルーティングパラメーターと組み合わせたものです。ネストされたページネーションを使用すると、ページネーションされたコレクションを何らかのプロパティやタグでグループ化できます。

たとえば、ページネーションされたMarkdownの投稿を何らかのタグでグループ化したい場合、以下のURLにマッチする`/src/pages/[tag]/[page].Astro`ページを作成してネストされたページネーションを使用します。

- `/red/1` (tag=red)
- `/red/2` (tag=red)
- `/blue/1` (tag=blue)
- `/green/1` (tag=green)

ネストされたページネーションは、`paginate()`の結果をグループごとに配列として`getStaticPaths()`から返すことで動作します。

以下の例では、上記のURLを作成するために、ネストされたページネーションを実装しています。

```astro /(?:[(]|=== )(tag)/ "params: { tag }" /const [{ ]*(page|params)/
---
// src/pages/[tag]/[page].astro
export function getStaticPaths({paginate}) {
  const allTags = ['red', 'blue', 'green'];
  const allPosts = await Astro.glob('../../posts/*.md');
  // すべてのタグに対して、paginate()の結果を返します。
  // その結果がどのタググループに対するものかAstroに伝えるために、
  // `{params: {tag}}`を必ず`paginate()`に渡してください。
  return allTags.flatMap((tag) => {
    const filteredPosts = allPosts.filter((post) => post.frontmatter.tag === tag);
    return paginate(filteredPosts, {
      params: { tag },
      pageSize: 10
    });
  });
}
const { page } = Astro.props;
const params = Astro.params;
```

## ページの除外

アンダースコア（`_`）を接頭辞としてファイル名に付けることで、ページやディレクトリをビルドから除外できます。アンダースコアで始まるファイルはルーターによって認識されず、`dist/`ディレクトリにも配置されません。

これを使用すると、一時的にページを無効にしたり、テストやユーティリティ、コンポーネントを関連するページと同じフォルダーに配置したりできます。

以下の例では、`src/pages/index.astro`と`src/pages/posts/post1.md`のみがページルートとHTMLファイルとしてビルドされます。

<FileTree>
- src/pages/
  - _hidden-directory/
    - page1.md
    - page2.md
  - _hidden-page.astro
  - **index.astro**
  - posts/
    - _SomeComponent.astro
    - _utils.js
    - **post1.md**
</FileTree>
